package com.atjava.nebula.frames.menu.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.springframework.security.core.GrantedAuthority;

import com.atjava.nebula.core.dao.ibatis.Condition;
import com.atjava.nebula.core.dao.ibatis.Order;
import com.atjava.nebula.core.exception.baseExp.BusinessException;
import com.atjava.nebula.core.model.TreeModel;
import com.atjava.nebula.core.service.impl.GenericServiceImpl;
import com.atjava.nebula.core.util.tree.TreeUtils;
import com.atjava.nebula.frames.auth.service.AuthService;
import com.atjava.nebula.frames.menu.SysMenu;
import com.atjava.nebula.frames.resources.SysResource;
import com.atjava.nebula.web.constant.ProjectConst;

public class MenuServiceImpl extends GenericServiceImpl<SysMenu,Short> implements MenuService{
	
	private AuthService authService;
	
	@SuppressWarnings("unchecked")
	public List<TreeModel> getMenuTreeList() throws BusinessException{
		//system menu
		Condition menuCond = new Condition();
		menuCond.addOrder(new Order("pid",true));
		List<?> menuList = list(menuCond);
		return TreeUtils.getTreeObjectList((List<TreeModel>) menuList);
	}
	
	@SuppressWarnings("unchecked")
	public SysMenu getMenuObject() throws BusinessException{
		//system menu
		Condition menuCond = new Condition();
		menuCond.addOrder(new Order("pid",true));
		List<?> menuList = list(menuCond);
		SysMenu menu = new SysMenu();
		menu.setPkid(ProjectConst.MENU_ROOT_ID);
		return (SysMenu) TreeUtils.getTreeObject((List<TreeModel>) menuList,menu);
	}
	
	@SuppressWarnings("unchecked")
	public SysMenu getUserCurrentMenuObject(Set<GrantedAuthority> authorities) throws BusinessException{
		
		List<Short> roleIdlist = new ArrayList<Short>();
		for (GrantedAuthority grantedAuthority : authorities) {
			roleIdlist.add(Short.parseShort(grantedAuthority.toString()));
		}
		
		List<SysResource> resList = authService.getResourcesByRoles(roleIdlist);
		List<Object> menuIdList = new ArrayList<Object>();
		for (SysResource sysResource : resList) {
			if (!menuIdList.contains(sysResource.getMenuId())) {
				menuIdList.add(sysResource.getMenuId());
			}
		}
		
		SysMenu curMenu = getMenuObject();
		curMenu.setChildNodes(new ArrayList<TreeModel>());
		
		for (Object menuId : menuIdList) {
			
			SysMenu sysMenu = getMenuObject();
			
			if (menuId.equals(sysMenu.getPkid())) {
				return sysMenu;
			} else {
				setCurMenu(curMenu, (SysMenu) GetCurMenu(menuId, sysMenu));
			}
		}
		
		return curMenu;
		
	}

	private void setCurMenu(SysMenu curMenu, SysMenu curNode) {
		boolean havePkId = false;
		
		for (int i = 0 ; i < curMenu.getChildNodes().size(); i++) {
			if (curMenu.getChildNodes().get(i).getPkid().equals(curNode.getPkid())) {
				havePkId = true;
				if (curNode.getChildNodes() != null) {
					setCurMenu((SysMenu) curMenu.getChildNodes().get(i), (SysMenu) curNode.getChildNodes().get(0));
				}
			}
		}
		
		if (!havePkId) {
			curMenu.getChildNodes().add(curNode);
		}
		
	}

	private TreeModel GetCurMenu(Object menuId, SysMenu sysMenu) throws BusinessException {
		
		for (int i = 0; i < sysMenu.getChildNodes().size(); i++) {
			
			if (sysMenu.getChildNodes().get(i).getPkid().equals(menuId)) {
				return sysMenu.getChildNodes().get(i);
			} else {
				if (sysMenu.getChildNodes().get(i).getChildNodes() != null) {
					TreeModel node = GetCurMenu(menuId, (SysMenu) sysMenu.getChildNodes().get(i));
					if (node != null) {
						sysMenu.getChildNodes().get(i).setChildNodes(new ArrayList<TreeModel>());
						sysMenu.getChildNodes().get(i).getChildNodes().add(node);
						return sysMenu.getChildNodes().get(i);
					}
				}
			}
		}
		
		return null;
		
	}

	public void setAuthService(AuthService authService) {
		this.authService = authService;
	}
	
}
